package cn.itcast.hotel;

import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@SpringBootTest
public class HotelIndexTest2 {

    //初始化RestHighLevelClient
    private RestHighLevelClient client;
    @BeforeEach
    public void begin(){
         client = new RestHighLevelClient(RestClient.builder(HttpHost.create("192.168.136.132:9200")));
    }

   @Autowired
    private IHotelService hotelService;


   //批量导入文档
    @Test
    public void bulkTest() throws IOException {
        //查询sql
        List<Hotel> hotelList = hotelService.list();
        //创建request
        BulkRequest request = new BulkRequest();

        for (Hotel hotel : hotelList) {
            //将对象转化为文档
            HotelDoc hotelDoc = new HotelDoc(hotel);
            //创建request子对象
            request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc), XContentType.JSON
            ));
        }
        client.bulk(request, RequestOptions.DEFAULT);
    }

    //es添加文档
    @Test
    public void indexTest() throws IOException {

        Hotel hotel = hotelService.getById(36934L);
        HotelDoc hotelDoc = new HotelDoc(hotel);

        //创建request
        IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString())
                .source(JSON.toJSONString(hotelDoc),XContentType.JSON);
        //发送请求
        client.index(request,RequestOptions.DEFAULT);
    }

    //es修改文档
    @Test
    public void updateTest() throws IOException {
        //创建request对象
        UpdateRequest request = new UpdateRequest("hotel", "36934");
        request.doc(
                "price",336
        );
        //发送请求
        client.update(request,RequestOptions.DEFAULT);
    }

    //查看文档
    @Test
    public void getTest() throws IOException {
        //创建requestduix
        GetRequest request = new GetRequest("hotel", "36934");
        //发送请求,得到响应
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        //解析响应结果
        String json = response.getSourceAsString();
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        //查看结果
        System.out.println(hotelDoc);
    }


    //根据文档id删除文档
    @Test
    public void deleteTest() throws IOException {
        //创建request对象
        DeleteRequest request = new DeleteRequest("hotel", "36934");
        //发送请求
        client.delete(request, RequestOptions.DEFAULT);
    }


    //=======================================================================
    //=========match_all match term range bool ==============================
    //=======================================================================

    //多条件查询
    @Test
    public void matchAllTest() throws IOException {
        SearchRequest searchRequest = new SearchRequest("hotel");
        //查询所有
        //searchRequest.source().query(QueryBuilders.matchAllQuery());
        //精确查询
        //searchRequest.source().query(QueryBuilders.termQuery("name","如家"));
        //分词查询
        //searchRequest.source().query(QueryBuilders.matchQuery("all","如家酒店"));
        //searchRequest.source().query(QueryBuilders.matchQuery("name","如家酒店"));
        //区间查询
        //searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(200));

        //复合查询
        //BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //boolQuery.must(QueryBuilders.matchQuery("all","如家酒店"));
        //boolQuery.filter(QueryBuilders.rangeQuery("price").gte(100).lte(200));
        //searchRequest.source().query(boolQuery);

        //排序
        //searchRequest.source().sort("price", SortOrder.DESC);
        //分页
        searchRequest.source().from(3).size(3);
        /*searchRequest.source().from(3);
        searchRequest.source().size(3);*/
        //高亮
        searchRequest.source().query(QueryBuilders.matchQuery("all","如家"));
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</ span>");
        highlightBuilder.requireFieldMatch(false);
        searchRequest.source().highlighter(highlightBuilder);

        //发送请求,得到响应
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //定义一个方法
        matchAll(response);
    }

    //解析响应结果
    private void matchAll(SearchResponse response) {
        SearchHits responseHits = response.getHits();
        //总条数
        long total = responseHits.getTotalHits().value;
        System.out.println("查询到的总数:"+total);

        SearchHit[] hits = responseHits.getHits();
        for (SearchHit hit : hits) {
            String source = hit.getSourceAsString();
            //解析响应结果
            //将读取到的source中的数据封装给HotelDoc
            HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);

            //高亮处理
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)){
                //获取高亮字段结果
                HighlightField highlightField = highlightFields.get("name");
                if (highlightField!=null){
                    Text[] fragments = highlightField.getFragments();
                    String nameHigligtField = fragments[0].toString();
                    hotelDoc.setName(nameHigligtField);
                }
            }
            System.out.println(hotelDoc);
        }
    }
}





















